package com.company.jdk8;
import  org.junit.Test;

import java.util.*;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @ProjectName: 复习java
 * @Package: com.company.jdk8
 * @ClassName: StreamApi
 * @Author: wym
 * @Date: 2020/9/13 21:55
 * @Version: 1.0
 */
public class StreamApi {

    @Test
    public  void  test1(){
        //Stream 是操作
        //Collection 是数据
        /**
         * stream 不会改变原对象 ，相反 他会 返回一个新  的stream 对象
         *
         */
        //创建对象  集合
//        List<Employee> employees = EmployeeData.getEmployees();
//        Stream<Employee> stream = employees.stream();
//        employees.parallelStream();
//        //stream  通过数组
//        int[] arr= new int[]{1,2,4,5,6};
//        IntStream stream1 = Arrays.stream(arr);
        List<Employee> employees = EmployeeData.getEmployees();
        //获取流
        Stream<Employee> stream = employees.stream();
//        stream.filter(new Predicate<Employee>() {
////            @Override
////            public boolean test(Employee employee) {
////                return false;
////            }
////        });
        //filter
        Stream<Employee> employeeStream = stream.filter(a -> a.getSalary() > 7000);
//        employeeStream.forEach(new Consumer<Employee>() {
//            @Override
//            public void accept(Employee employee) {
//
//            }
//        });
        employeeStream.forEach(a-> System.out.println(a));
        System.out.println("---------------------------");
        //limit(n) 一截断流 ，使其元素不能超过 给定数量
        List<Employee> list = EmployeeData.getEmployees();

        //list.stream().limit(3).forEach(System.out::print);

        //skip(n)跳过元素，返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个，则返回一个空流。与 limit(n) 互补 丢弃 前面的
        //list.stream().skip(3).limit(3).forEach(System.out::print);

        //筛选 通过 流生成 元素的hashcode equals 去重复元素
//        list.add(new Employee(1010,"刘强东",40,8000));
//        list.add(new Employee(1010,"刘强东",41,8000));
//        list.add(new Employee(1010,"刘强东",40,8000));
//        list.add(new Employee(1010,"刘强东",40,8000));
//        list.add(new Employee(1010,"刘强东",40,8000));

//        list.stream().distinct().forEach(System.out::print);

    }

    @Test
    public void test2(){
//        List<Integer> list = Arrays.asList(1, 2, 3, 45, 5);
//
//        List<Integer> list1 = Arrays.asList(4);
//        boolean b = list1.addAll(list);
//
//        //System.out.println(list);
//        List<Integer>ints=Arrays.asList(1,2,3,4,5,6,7,8,9,10);
//        Stream<Integer>evenIntegers=ints.stream().filter(i->i.intValue()%2==0);
//
//        Stream<Integer>oddIntegers=ints.stream().filter(i->i.intValue()%2!=0);
//
//        evenIntegers.forEach(i->System.out.println("i is even"));
//        oddIntegers.forEach(i->System.out.println("i is old"));
        List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
        list.stream().map(String::toUpperCase).forEach(System.out::println);
        //获取 员工姓名 长度 大于3的员工的姓名
        List<Employee> employees = EmployeeData.getEmployees();
        Stream<String> stringStream = employees.stream().map(Employee::getName);
        stringStream.filter(name->name.length()>3).forEach(System.out::println);
        System.out.println("-----------------");
        //flatMap(Function f)——接收一个函数作为参数，将流中的每个值都换成另一个流，然后把所有流连接成一个流。
        Stream<Character> characterStream = list.stream().flatMap(StreamApi::fromStringToStream);
        characterStream.forEach(System.out::println);

    }

    //将字符串中的多个字符构成的集合转换为对应的Stream的实例
    public static Stream<Character> fromStringToStream(String str){//aa
        ArrayList<Character> list = new ArrayList<>();
        for(Character c : str.toCharArray()){
            list.add(c);
        }
        return list.stream();
    }
    @Test
    public  void  test3(){
        List<Employee> employees = EmployeeData.getEmployees();
        //        allMatch(Predicate p)——检查是否匹配所有元素。
        // 练习：是否所有的员工的年龄都大于18
        boolean b = employees.stream().allMatch(e -> e.getAge() > 18);
        System.out.println(b );
        //        anyMatch(Predicate p)——检查是否至少匹配一个元素。
//         练习：是否存在员工的工资大于 10000
        boolean b1 = employees.stream().anyMatch(e -> e.getSalary() > 10000);
        System.out.println(b1);
        //        noneMatch(Predicate p)——检查是否没有匹配的元素。
        //          练习：是否存在员工姓“雷” 有匹配的返回 false
        boolean a = employees.stream().noneMatch(e -> e.getName().startsWith("雷"));
        System.out.println(a);
        //findFirst--返回第一个元素
        Optional<Employee> first = employees.stream().findFirst();
        System.out.println(first);
        //        findAny——返回当前流中的任意元素
        Optional<Employee> employee1 = employees.parallelStream().findAny();
        System.out.println(employee1);
    }

    @Test
    public void test4(){
        //  reduce(T identity, BinaryOperator)——可以将流中元素反复结合起来，得到一个值。返回 T
//        练习1：计算1-10的自然数的和
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        Integer sum = list.stream().reduce(0, (a,b)->a+b);
        System.out.println(sum);

        //        reduce(BinaryOperator) ——可以将流中元素反复结合起来，得到一个值。返回 Optional<T>
//        练习2：计算公司所有员工工资的总和
        List<Employee> employees = EmployeeData.getEmployees();
        Stream<Double> salaryStream = employees.stream().map(Employee::getSalary);
        //Optional<Double> sumMoney = salaryStream.reduce((a, b) -> a + b); reduce 减少
        Optional<Double> reduce = salaryStream.reduce(Double::sum);
        System.out.println(reduce.get());
    }

    @Test
    public void  test5(){
        //统计是最后
        List<Employee> employees = EmployeeData.getEmployees();
        // count——返回流中元素的总个数
        long count = employees.stream().filter(e -> e.getSalary() > 5000).count();
        System.out.println(count);
        // 练习：返回最高的工资：
        Stream<Double> salaryStream = employees.stream().map(e -> e.getSalary());
        Optional<Double> maxSalary = salaryStream.max(Double::compare);
        System.out.println(maxSalary);
        Optional<Employee> employee = employees.stream().min(Comparator.comparingDouble(Employee::getSalary));
        System.out.println(employee);
        System.out.println();
        //        forEach(Consumer c)——内部迭代
        employees.stream().forEach(System.out::println);
        //使用集合的遍历操作
        employees.forEach(System.out::println);
    }
    @Test
    public void  test6(){
        //collect(Collector c)——将流转换为其他形式。接收一个 Collector接口的实现，用于给Stream中元素做汇总的方法
        //练习1：查找工资大于6000的员工，结果返回为一个List或Set
        List<Employee> employees = EmployeeData.getEmployees();
        List<Employee> employeeList = employees.stream().filter(e -> e.getSalary() > 6000).collect(Collectors.toList());
        employeeList.forEach(System.out::println);
        System.out.println();
        //转set 集合
        Set<Employee> employeeSet = employees.stream().filter(e -> e.getSalary() > 6000).collect(Collectors.toSet());
        employeeSet.forEach(System.out::println);
    }


}
